package com.scut.campus.infra.redis;

import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.stereotype.Component;

import java.util.Collections;
import java.util.List;

@Component
public class RedisFixedSizeQueue {

    private final RedisTemplate<String, Object> redisTemplate;
    private final DefaultRedisScript<Long> pushScript;
    private static final int MAX_SIZE = 10;

    public RedisFixedSizeQueue(RedisTemplate<String, Object> redisTemplate) {
        this.redisTemplate = redisTemplate;

        // 初始化Lua脚本
        this.pushScript = new DefaultRedisScript<>(
                "local maxSize = tonumber(ARGV[2])\n" +
                        "if not maxSize or maxSize <= 0 then\n" +
                        "    return redis.error_reply('maxSize must be postive')\n" +
                        "end\n" +
                        "local currentLen = redis.call('RPUSH', KEYS[1], ARGV[1])\n" +
                        "if currentLen > maxSize then\n" +
                        "    redis.call('LPOP', KEYS[1])\n" +
                        "    return maxSize\n" +
                        "end\n" +
                        "return currentLen",
                Long.class
        );
    }

    /**
     * 原子性地向队列添加元素，保持固定大小
     */
    public long push(String queueKey, Object value) {
        return redisTemplate.execute(
                pushScript,
                Collections.singletonList(queueKey),
                value, MAX_SIZE
        );
    }

    /**
     * 获取队列中的所有元素
     *
     * @param queueKey 队列的key
     * @return 包含所有元素的列表
     */
    public List<Object> getAllFromQueue(String queueKey) {
        // 获取列表所有元素(0到-1表示全部)
        return redisTemplate.opsForList().range(queueKey, 0, -1);
    }

    /**
     * 获取队列当前大小
     *
     * @param queueKey 队列的key
     * @return 队列大小
     */
    public Long getQueueSize(String queueKey) {
        return redisTemplate.opsForList().size(queueKey);
    }

    /**
     * 清空队列
     *
     * @param queueKey 队列的key
     */
    public void clearQueue(String queueKey) {
        redisTemplate.delete(queueKey);
    }

}